# -*- coding: utf-8 -*-
"""
FLASK 部署模型
CHANGELOG :
    20250415 :
    1. 新增通义千问商业模型，为了解决单句话中含有多个车型的对比问题
"""
import json, codecs, time, os, logging
from datetime import datetime

from flask import Flask, request
from flask_pydantic_spec import FlaskPydanticSpec, Response, Request
from pydantic import BaseModel
from flasgger import Swagger, swag_from

from analyze import Assembly
import settings
from settings import *

assemble = Assembly()

app = Flask(__name__)
spec = FlaskPydanticSpec(
    title="Customer Voice VoC : 20250415", version="8"
)
spec.register(app)

# Swagger 配置
app.config['SWAGGER'] = {
    'title': 'Customer Voice VoC 项目 : 20250415',
    'uiversion': 3,
    'openapi': '3.0.2'
}
swagger = Swagger(app)


from utils.tool import RetryManager, setRotatingRootLogger

# 日志相关
setRotatingRootLogger('./logs/qwen-logger.log')
logging.info({
    'type': 'INFO',
    'model_deploy_mode': settings.MODEL_FLAG,
    'model_name': settings.MODEL_NAME,
    'info': "===START DEPLOY===",
    'date': str(datetime.now())
})


'''
Clean_Sentence
'''


class clean_sentence_Request(BaseModel):
    customer_voice: str


class clean_sentence_Response(BaseModel):
    message: dict


@app.route('/clean_sentence', methods=['POST'])
@spec.validate(body=Request(clean_sentence_Request),
               resp=Response(HTTP_201=clean_sentence_Response))
@swag_from({
    'tags': ['1.工具类'],
    'summary': '1.1客户声音清洗',
    'requestBody': {
        'required': True,
        'content': {
            'application/json': {
                'schema': clean_sentence_Request.schema()
            }
        }
    },
    'responses': {
        '201': {
            'description': '客户 customer vocie 清洗结果',
            'content': {
                'application/json': {
                    'schema': clean_sentence_Response.schema()
                }
            }
        }
    }
})
def clean_sentence_func():
    post_parameters = clean_sentence_Request(**request.context.body.dict())
    customer_voice = post_parameters.customer_voice
    if not isinstance(customer_voice, str):
        message = {"status_code": 500, 'result': ''}
        return clean_sentence_Response(message=message).dict(), 201
    else:
        customer_voice = assemble.clean_sentence(
            customer_voice=customer_voice,
        )
        return clean_sentence_Response(message={
            'result': customer_voice,
            'status_code': 200
        }).dict(), 201


'''
Sentiment_Analysis
TODO : 20250213 新增vehicle的内容，指定车型中的问题
'''


class sentiment_analysis_Request(BaseModel):
    customer_voice: str
    content: str
    vehicle: str


class sentiment_analysis_Response(BaseModel):
    message: dict


@app.route('/sentiment_analysis', methods=['POST'])
@spec.validate(body=Request(sentiment_analysis_Request), resp=Response(HTTP_201=sentiment_analysis_Response))
@swag_from({
    'tags': ['1.工具类'],
    'summary': '1.2 情感分析，带指定车型',
    'requestBody': {
        'required': True,
        'content': {
            'application/json': {
                'schema': sentiment_analysis_Request.schema()
            }
        }
    },
    'responses': {
        '201': {
            'description': '反馈客户反馈中指定内容的情感',
            'content': {
                'application/json': {
                    'schema': sentiment_analysis_Response.schema()
                }
            }
        }
    }
})
def sentiment_analysis_func():
    post_parameters = sentiment_analysis_Request(
        **request.context.body.dict()
    )
    customer_voice = post_parameters.customer_voice
    content = post_parameters.content
    vehicle = post_parameters.vehicle
    if ',' in vehicle:
        vehicle_split = vehicle.split(',')
        vehicle = vehicle_split[0].strip()
    else:
        vehicle = vehicle
    if isinstance(customer_voice, str) and isinstance(content, str):
        sentiment = assemble.sentiment(
            customer_voice=customer_voice,
            content=content,
            vehicle=vehicle
        )
        return sentiment_analysis_Response(message={
            'result': sentiment,
            'status_code': 200
        }).dict(), 201
    else:
        message = {"status_code": 500, 'result': ''}
        return sentiment_analysis_Response(message=message).dict(), 201


'''
NER Analysis
TODO : 20250213 新增vehicle的内容，指定车型中的问题
'''

class ner_analysis_Request(BaseModel):
    customer_voice: str
    content: str

class ner_analysis_Response(BaseModel):
    message: dict


@app.route('/ner_analysis', methods=['POST'])
@spec.validate(body=Request(ner_analysis_Request),
               resp=Response(HTTP_201=ner_analysis_Response))
@swag_from({
    'tags': ['1.工具类'],
    'summary': '1.3 (NER) named entity recognization',
    'requestBody': {
        'required': True,
        'content': {
            'application/json': {
                'schema': ner_analysis_Request.schema()
            }
        }
    },
    'responses': {
        '201': {
            'description': '反馈客户反馈中和目标内容哪句话相关',
            'content': {
                'application/json': {
                    'schema': ner_analysis_Response.schema()
                }
            }
        }
    }
})
def ner_analysis_func():
    post_parameters = ner_analysis_Request(
        **request.context.body.dict()
    )
    customer_voice = post_parameters.customer_voice
    content = post_parameters.content
    if isinstance(customer_voice, str):
        ner = assemble.ner(
            customer_voice=customer_voice,
            content=content
        )
        return ner_analysis_Response(message={
            'result': ner,
            'status_code': 200
        }).dict(), 201
    else:
        message = {"status_code": 500, 'result': ''}
        return ner_analysis_Response(message=message).dict(), 201


'''
sentence split per vehicle
'''

class sentence_split_Request(BaseModel):
    customer_voice: str
    vehicle: str

class sentence_split_Response(BaseModel):
    message: dict


@app.route('/sentence_split', methods=['POST'])
@spec.validate(body=Request(sentence_split_Request),
               resp=Response(HTTP_201=sentence_split_Response))
@swag_from({
    'tags': ['1.工具类'],
    'summary': '1.4 sentence split per vehicle',
    'requestBody': {
        'required': True,
        'content': {
            'application/json': {
                'schema': sentence_split_Request.schema()
            }
        }
    },
    'responses': {
        '201': {
            'description': '按照车辆对原始语句拆分',
            'content': {
                'application/json': {
                    'schema': sentence_split_Response.schema()
                }
            }
        }
    }
})
def sentence_split_func():
    post_parameters = sentence_split_Request(
        **request.context.body.dict()
    )
    customer_voice = post_parameters.customer_voice
    vehicle = post_parameters.vehicle
    if isinstance(customer_voice, str):
        sentence_split = assemble.assemble(
            sentence=customer_voice,
            type='sentence_split',
            vehicle=vehicle
        )
        return sentence_split_Response(message={
            'result': sentence_split,
            'status_code': 200
        }).dict(), 201
    else:
        message = {"status_code": 500, 'result': ''}
        return ner_analysis_Response(message=message).dict(), 201







'''
clarify forum
TODO : 改变从原来的只能识别论坛中是否是质量问题，将论坛中的数据区分的更精细
'''


class clarify_forum_Request(BaseModel):
    customer_voice: str


class clarify_forum_Response(BaseModel):
    message: dict


@app.route('/clarify_forum_analysis', methods=['POST'])
@spec.validate(body=Request(clarify_forum_Request),
               resp=Response(HTTP_201=clarify_forum_Response))
@swag_from({
    'tags': ['2. 低级分类'],
    'summary': '2.2 分类论坛中数据',
    'requestBody': {
        'required': True,
        'content': {
            'application/json': {
                'schema': clarify_forum_Request.schema()
            }
        }
    },
    'responses': {
        '201': {
            'description': '''分类论坛中的数据 : 
                            "车辆质量与可靠性",
                            "车辆评价体验",
                            "车辆营销内容",
                            "不同车型间对比",
                            "车企商业信息",
                            "社区与活动",
                            "其他未分类信息",
                ''',
            'content': {
                'application/json': {
                    'schema': clarify_forum_Response.schema()
                }
            }
        }
    }
})
def clarify_forum_func():
    post_parameters = clarify_forum_Request(**request.context.body.dict())
    customer_voice = post_parameters.customer_voice
    type = 'clarify_forum'
    if isinstance(customer_voice, str):
        forum_types = assemble.assemble(
            sentence=customer_voice,
            type=type
        )
        return clarify_forum_Response(message={
            'result': forum_types,
            'status_code': 200
        }).dict(), 201
    else:
        message = {"status_code": 500, 'result': ''}
        return clarify_forum_Response(message=message).dict(), 201


'''
clarify vehicle relevant 
'''


class clarify_vehicle_relevant_Request(BaseModel):
    customer_voice: str


class clarify_vehicle_relevant_Response(BaseModel):
    message: dict

@app.route('/clarify_vehicle_relevant_analysis', methods=['POST'])
@spec.validate(body=Request(clarify_vehicle_relevant_Request),
               resp=Response(HTTP_201=clarify_vehicle_relevant_Response))
@swag_from({
    'tags': ['2. 低级分类'],
    'summary': '2.1 识别是否与车辆相关',
    'requestBody': {
        'required': True,
        'content': {
            'application/json': {
                'schema': clarify_vehicle_relevant_Request.schema()
            }
        }
    },
    'responses': {
        '201': {
            'description': '[客户反馈和车辆相关,客户反馈和车辆不相关,客户反馈中无法判断是否和车辆相关]',
            'content': {
                'application/json': {
                    'schema': clarify_vehicle_relevant_Response.schema()
                }
            }
        }
    }
})
def clarify_vehicle_relevant_func():
    post_parameters = clarify_vehicle_relevant_Request(**request.context.body.dict())
    customer_voice = post_parameters.customer_voice
    type = 'clarify_vehicle_relevant'
    if isinstance(customer_voice, str):
        if_vehicle_relevant = assemble.assemble(
            sentence=customer_voice,
            type=type
        )
        return clarify_vehicle_relevant_Response(message={
            'result': if_vehicle_relevant,
            'status_code': 200
        }).dict(), 201
    else:
        message = {"status_code": 500, 'result': ''}
        return clarify_vehicle_relevant_Response(message=message).dict(), 201


'''
purchase clarify
'''


class purchase_clarify_Request(BaseModel):
    customer_voice: str


class purchase_clarify_Response(BaseModel):
    message: dict


@app.route('/purchase_clarify_analysis', methods=['POST'])
@spec.validate(body=Request(purchase_clarify_Request), resp=Response(HTTP_201=purchase_clarify_Response))
@swag_from({
    'tags': ['2. 低级分类'],
    'summary': '2.3 识别购车欲望',
    'requestBody': {
        'required': True,
        'content': {
            'application/json': {
                'schema': purchase_clarify_Request.schema()
            }
        }
    },
    'responses': {
        '201': {
            'description': '''[
                    强烈购买车辆意愿
                    中等购买车辆意愿
                    低购买车辆意愿
                    无法判别购车意愿
                ]''',
            'content': {
                'application/json': {
                    'schema': purchase_clarify_Response.schema()
                }
            }
        }
    }
})
def purchase_clarify_func():
    post_parameters = purchase_clarify_Request(**request.context.body.dict())
    customer_voice = post_parameters.customer_voice
    type = 'purchase_prompt'
    if isinstance(customer_voice, str) and isinstance(type, str):
        purchase_clarify = assemble.assemble(
            sentence=customer_voice,
            type=type  # "purchase_prompt"
        )
        return purchase_clarify_Response(message={
            'result': purchase_clarify,
            'status_code': 200
        }).dict(), 201
    else:
        message = {"status_code": 500, 'result': ''}
        return purchase_clarify_Response(message=message).dict(), 201


'''
Feeling Analysis without vehicle
'''


class feeling_Request_withoutvehicle(BaseModel):
    customer_voice: str

class feeling_Response_withoutvehicle(BaseModel):
    message: dict


@app.route('/feel_analysis_withoutvehicle', methods=['POST'])
@spec.validate(body=Request(feeling_Request_withoutvehicle),
               resp=Response(HTTP_201=feeling_Response_withoutvehicle))
@swag_from({
    'tags': ['3. CuZu Analysis'],
    'summary': 'cuzu analysis without vehicle',
    'requestBody': {
        'required': True,
        'content': {
            'application/json': {
                'schema': feeling_Request_withoutvehicle.schema()
            }
        }
    },
    'responses': {
        '201': {
            'description': '客户角度对车辆感受的分析结果',
            'content': {
                'application/json': {
                    'schema': feeling_Response_withoutvehicle.schema()
                }
            }
        }
    }
})
def feel_func():
    post_parameters = feeling_Request_withoutvehicle(**request.context.body.dict())
    customer_voice = post_parameters.customer_voice
    type = "feel" # feel
    if isinstance(customer_voice, str) :
        feel_result = assemble.assemble(
            sentence=customer_voice,
            type=type,  # "feel"
        )
        return feeling_Response_withoutvehicle(message={
            'result': feel_result,
            'status_code': 200
        }).dict(), 201
    else:
        message = {"status_code": 500, 'result': ''}
        return feeling_Response_withoutvehicle(message=message).dict(), 201


'''
Feeling Analysis with vehicle
'''


class feeling_Request_withvehicle(BaseModel):
    customer_voice: str
    vehicle: str

class feeling_Response_withvehicle(BaseModel):
    message: dict


@app.route('/feel_analysis_withvehicle', methods=['POST'])
@spec.validate(body=Request(feeling_Request_withvehicle),
               resp=Response(HTTP_201=feeling_Response_withvehicle))
@swag_from({
    'tags': ['3. CuZu Analysis'],
    'summary': 'cuzu analysis with vehicle',
    'requestBody': {
        'required': True,
        'content': {
            'application/json': {
                'schema': feeling_Request_withvehicle.schema()
            }
        }
    },
    'responses': {
        '201': {
            'description': '客户角度对车辆感受的分析结果',
            'content': {
                'application/json': {
                    'schema': feeling_Response_withvehicle.schema()
                }
            }
        }
    }
})
def feel_func_withvehicle():
    post_parameters = feeling_Request_withvehicle(**request.context.body.dict())
    customer_voice = post_parameters.customer_voice
    vehicle = post_parameters.vehicle
    type = "feel_withvehicle" # feel
    if isinstance(customer_voice, str) :
        feel_result = assemble.assemble(
            sentence=customer_voice,
            type=type,  # "feel_withvehicle"
            vehicle=vehicle
        )
        return feeling_Response_withvehicle(message={
            'result': feel_result,
            'status_code': 200
        }).dict(), 201
    else:
        message = {"status_code": 500, 'result': ''}
        return feeling_Response_withvehicle(message=message).dict(), 201





if __name__ == '__main__':
    app.run(host='0.0.0.0',
            port=36687,
            debug=True)








